﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;

namespace Kokomo.Environment
{
	/// <summary>
	/// Implements a <see cref="DataTemplateSelector"/> that selects templates
	/// based on attributes.
	/// </summary>
	/// <remarks>
	/// This implementation checks
	/// for <see cref="ViewTypeAttribute"/> and creates an instance of <see cref="ViewTypeAttribute.ViewType"/>,
	/// setting the <see cref="FrameworkElement.DataContext"/> property of the instantiated view
	/// object to the viewmodel.
	/// <para>There is no public constructor.  Use <see cref="Default"/> instead.</para>
	/// </remarks>
	/// <seealso cref="ViewTypeAttribute"/>
	public class AttributedViewTemplateSelector : DataTemplateSelector
	{
		static AttributedViewTemplateSelector()
		{
			Default = new AttributedViewTemplateSelector();
		}

		/// <summary>
		/// Initializes a new instance of <see cref="AttributedViewTemplateSelector"/>.
		/// </summary>
		protected AttributedViewTemplateSelector()
		{
		}

		/// <summary>
		/// Gets the default instance of <see cref="AttributedViewTemplateSelector"/>.
		/// </summary>
		public static AttributedViewTemplateSelector Default { get; private set; }

		// Parameters:
		//   item:
		//     The data object for which to select the template.
		//
		//   container:
		//     The data-bound object.
		//
		// Returns:
		//     Returns a System.Windows.DataTemplate or null. The default value is null.
		/// <summary>
		/// When overridden in a derived class, returns a System.Windows.DataTemplate
		/// based on custom logic.
		/// </summary>
		/// <param name="item">The data object for which to select the template.</param>
		/// <param name="container">The data-bound object.</param>
		/// <returns>Returns a <see cref="DataTemplate"/> or <c>null</c>. The default value is <c>null</c>.</returns>
		/// <remarks>
		/// See remarks under <see cref="AttributedViewTemplateSelector"/>
		/// for implementation details.
		/// </remarks>
		public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
		{
			if (item == null) return null;

			Type type = item.GetType();

			ViewTypeAttribute viewTypeAttribute = type.GetCustomAttribute<ViewTypeAttribute>();
			if (viewTypeAttribute == null) return base.SelectTemplate(item, container);

			// Create template
			DataTemplate viewTemplate = new DataTemplate(type)
			{
				VisualTree = new FrameworkElementFactory(viewTypeAttribute.ViewType)
			};

			return viewTemplate;
		}
	}
}
